Azure Firewall/Template - Inspecting traffic to PE with Azure Firewall/DedicatedPeVnet.tf (366 lines of code) (raw):

terraform { required_version = ">=0.12" required_providers { azurerm = { source = "hashicorp/azurerm" version = ">=2.46.0" } } } provider "azurerm" { features {} } data "azurerm_client_config" "current" {} resource "random_string" "random" { length = 6 special = false upper = false } resource "random_password" "password" { length = 12 lower = true numeric = true special = true upper = true } //Resource Group DedicatedPEVnet resource "azurerm_resource_group" "rg" { name = "DedicatedPEVnet" location = "eastus2" } //Keyvault resource "azurerm_key_vault" "mykeyvault" { name = "${random_string.random.result}-kv" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name tenant_id = data.azurerm_client_config.current.tenant_id sku_name = "standard" purge_protection_enabled = false access_policy { tenant_id = data.azurerm_client_config.current.tenant_id object_id = data.azurerm_client_config.current.object_id secret_permissions = [ "List", "Set", "Get", ] } } //VM Secret resource "azurerm_key_vault_secret" "vmsecret" { name = "AzureUser" value = "${random_password.password.result}" key_vault_id = azurerm_key_vault.mykeyvault.id } //MySql Secret resource "azurerm_key_vault_secret" "mysqlsecret" { name = "mysqladmin" value = "${random_password.password.result}" key_vault_id = azurerm_key_vault.mykeyvault.id } //MySQL PaaS Service resource "azurerm_mysql_server" "mysql" { name = "${random_string.random.result}-mysql" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name version = "8.0" administrator_login = "mysqladmin" administrator_login_password = "${random_password.password.result}" ssl_enforcement_enabled = "true" sku_name = "GP_Gen5_2" } //MySQL Private Endpoint resource "azurerm_private_endpoint" "mysqlpe" { name = "${random_string.random.result}-endpoint" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name subnet_id = azurerm_subnet.MySQL.id private_service_connection { name = "${random_string.random.result}-privateserviceconnection" private_connection_resource_id = azurerm_mysql_server.mysql.id subresource_names = [ "mysqlServer" ] is_manual_connection = false } } //Public IPs (Firewall) resource "azurerm_public_ip" "transitip" { name = "FWTransitIP" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name allocation_method = "Static" sku = "Standard" } //Firewall Policy Premium resource "azurerm_firewall_policy" "FwPolicy" { name = "FwPolicy" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name sku = "Premium" private_ip_ranges = ["10.10.10.0/24","10.10.11.0/24"] } //Firewall Policy Rule Collections and Rules resource "azurerm_firewall_policy_rule_collection_group" "FwLabRcg" { name = "FwLabRcg" firewall_policy_id = azurerm_firewall_policy.FwPolicy.id priority = 600 application_rule_collection { name = "app_rule_collection1" priority = 500 action = "Allow" rule { name = "app_rule_collection1_rule1" protocols { type = "Http" port = 80 } protocols { type = "Https" port = 443 } source_addresses = ["10.10.11.0/24"] destination_fqdns = ["*.microsoft.com"] } rule { name = "app_rule_collection1_rule2" protocols { type = "Https" port = 443 } source_addresses = ["10.10.11.0/24"] destination_fqdns = ["${azurerm_mysql_server.mysql.name}.mysql.database.azure.com"] } } network_rule_collection { name = "network_rule_collection1" priority = 400 action = "Deny" rule { name = "network_rule_collection1_rule1" protocols = ["TCP","UDP"] source_addresses = ["10.10.11.0/24"] destination_addresses = ["8.8.8.8"] destination_ports = ["80","443"] } } network_rule_collection { name = "network_rule_collection2" priority = 395 action = "Allow" rule { name = "network_rule_collection2_rule1" protocols = ["TCP"] source_addresses = ["10.10.11.0/24"] destination_addresses = ["10.10.12.4/32"] destination_ports = ["443","3306"] } } nat_rule_collection { name = "nat_rule_collection1" priority = 300 action = "Dnat" rule { name = "nat_rule_collection1_rule1" protocols = ["TCP","UDP"] source_addresses = ["*"] destination_address = azurerm_public_ip.transitip.ip_address destination_ports = ["3389"] translated_address = "10.10.11.4" translated_port = "3389" } } } //Route Tables (UDRs) resource "azurerm_route_table" "Spoke1RT" { name = "Spoke1RT" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name disable_bgp_route_propagation = "false" route { name = "DefaultRoute" address_prefix = "0.0.0.0/0" next_hop_type = "VirtualAppliance" next_hop_in_ip_address = "10.10.10.4" } route { name = "MySqlPE" address_prefix = "10.10.12.4/32" next_hop_type = "VirtualAppliance" next_hop_in_ip_address = "10.10.10.4" } } //Hub Vnet resource "azurerm_virtual_network" "hubvnet" { name = "HubVnet" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name address_space = ["10.10.10.0/24"] } resource "azurerm_subnet" "AzureFirewallSubnet" { name = "AzureFirewallSubnet" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.hubvnet.name address_prefixes = ["10.10.10.0/26"] } //Spoke Vnet (VM Vnet) resource "azurerm_virtual_network" "spokevnet1" { name = "SpokeVnet1" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name address_space = ["10.10.11.0/24"] } resource "azurerm_subnet" "AppSubnet" { name = "AppSubnet" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.spokevnet1.name address_prefixes = ["10.10.11.0/27"] } //PE Vnet resource "azurerm_virtual_network" "pevnet" { name = "PeVnet" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name address_space = ["10.10.12.0/24"] } resource "azurerm_subnet" "MySQL" { name = "mysqlsubnet" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.pevnet.name address_prefixes = ["10.10.12.0/27"] } //Route Table + Subnet Association resource "azurerm_subnet_route_table_association" "AppSubnetRT" { subnet_id = azurerm_subnet.AppSubnet.id route_table_id = azurerm_route_table.Spoke1RT.id } //Hub and Spoke Vnet Peering resource "azurerm_virtual_network_peering" "HubToSpoke1" { name = "HubToSpoke1" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.hubvnet.name remote_virtual_network_id = azurerm_virtual_network.spokevnet1.id } resource "azurerm_virtual_network_peering" "Spoke1ToHub" { name = "HubToSpoke1" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.spokevnet1.name remote_virtual_network_id = azurerm_virtual_network.hubvnet.id } //Hub and PE Vnet Peering resource "azurerm_virtual_network_peering" "HubToPe" { name = "HubToPE" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.hubvnet.name remote_virtual_network_id = azurerm_virtual_network.pevnet.id } resource "azurerm_virtual_network_peering" "PeToHub" { name = "PeToHub" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.pevnet.name remote_virtual_network_id = azurerm_virtual_network.hubvnet.id } //Azure Firewall Premium resource "azurerm_firewall" "azfw" { name = "azfw" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name firewall_policy_id = azurerm_firewall_policy.FwPolicy.id sku_tier = "Premium" sku_name = "AZFW_VNet" ip_configuration { name = "transitconfig" subnet_id = azurerm_subnet.AzureFirewallSubnet.id public_ip_address_id = azurerm_public_ip.transitip.id } } //AppVm1 Network Interface resource "azurerm_network_interface" "AppVm1Nic1" { name = "AppVm1Nic1" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name ip_configuration { name = "AppVmNicConfig1" subnet_id = azurerm_subnet.AppSubnet.id private_ip_address_allocation = "Dynamic" } } //AppVm1 resource "azurerm_virtual_machine" "AppVm1" { name = "AppVm1" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name network_interface_ids = [azurerm_network_interface.AppVm1Nic1.id] vm_size = "Standard_DS1_V2" storage_image_reference { publisher = "MicrosoftWindowsDesktop" offer = "windows-11" sku = "win11-22h2-pro" version = "latest" } storage_os_disk { name = "myosdisk1" caching = "ReadWrite" create_option = "FromImage" managed_disk_type = "Standard_LRS" } os_profile { computer_name = "appvm1" admin_username = "AzureUser" admin_password = "${random_password.password.result}" } os_profile_windows_config { } } //Azure Private DNS Zone (mysql.database.azure.com) and A record resource "azurerm_private_dns_zone" "mysqlprivdnszone" { name = "privatelink.mysql.database.azure.com" resource_group_name = azurerm_resource_group.rg.name } resource "azurerm_private_dns_a_record" "mysqldnsrecord" { name = azurerm_mysql_server.mysql.name zone_name = azurerm_private_dns_zone.mysqlprivdnszone.name resource_group_name = azurerm_resource_group.rg.name ttl = 300 records = ["10.10.12.4"] } resource "azurerm_private_dns_zone_virtual_network_link" "example" { name = "SpokeVnet1Link" resource_group_name = azurerm_resource_group.rg.name private_dns_zone_name = azurerm_private_dns_zone.mysqlprivdnszone.name virtual_network_id = azurerm_virtual_network.spokevnet1.id } //Log Analytics Workspace used by the Firewall's Diagnostic Settings resource "azurerm_log_analytics_workspace" "DiagSettingsLaw" { name = "DiagSettingsLaw" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name sku = "PerGB2018" retention_in_days = 30 } // Firewall's Diagnostic Settings (Resource Specific Logs) resource "azurerm_monitor_diagnostic_setting" "azfw-diag" { name = "RsFwLogDedicatedPeVnet" target_resource_id = azurerm_firewall.azfw.id log_analytics_workspace_id = azurerm_log_analytics_workspace.DiagSettingsLaw.id log_analytics_destination_type = "Dedicated" log { category = "AZFWApplicationRule" enabled = true retention_policy { enabled = true } } log { category = "AZFWNetworkRule" enabled = true retention_policy { enabled = true } } metric { category = "AllMetrics" enabled = false retention_policy { enabled = false } } }